package Study;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayInputStream;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.security.GeneralSecurityException;
public class Main {
    /** Interval of time (seconds) between successive changes of this counter's value. */
    private static final long mTimeStep=30;

    /**
     * Earliest time instant (seconds since UNIX epoch) at which this counter assumes the value of
     * {@code 0}.
     */
    private static final long mStartTime=0;
    public static long getValueAtTime(long time) {

        // According to the RFC:
        // T = (Current Unix time - T0) / X, where the default floor function is used.
        //   T  - counter value,
        //   T0 - start time.
        //   X  - time step.

        // It's important to use a floor function instead of simple integer division. For example,
        // assuming a time step of 3:
        // Time since start time: -6 -5 -4 -3 -2 -1  0  1  2  3  4  5  6
        // Correct value:         -2 -2 -2 -1 -1 -1  0  0  0  1  1  1  2
        // Simple division / 3:   -2 -1 -1 -1  0  0  0  0  0  1  1  1  2
        //
        // To avoid using Math.floor which requires imprecise floating-point arithmetic, we
        // we compute the value using integer division, but using a different equation for
        // negative and non-negative time since start time.
        long timeSinceStartTime = time - mStartTime;
        if (timeSinceStartTime >= 0) {
            return timeSinceStartTime / mTimeStep;
        } else {
            return (timeSinceStartTime - (mTimeStep - 1)) / mTimeStep;
        }
    }
    private static byte[] decodeKey(String secret) {
        return Base32.decode(secret);
    }

    static String TOTP(String key) throws GeneralSecurityException {
        long otpState =getValueAtTime(System.currentTimeMillis()/1000);
        String secret=key;
        return computePin(secret,otpState,null);
    }
    public static  void main(String[] arg) throws GeneralSecurityException {
//        byte[] a=Base32.decode("youareok");
//        System.out.println( );
       System.out.println(TOTP.TOTP("youareok"));
    }
    private static String computePin(String secret, long otpState, byte[] challenge) throws GeneralSecurityException {
            Mac m=Mac.getInstance("HMACSHA1");
            m.init(new SecretKeySpec(decodeKey(secret),""));
            PasscodeGenerator pcg=new PasscodeGenerator(m,6);
            return (challenge == null) ?
                    pcg.generateResponseCode(otpState) :
                    pcg.generateResponseCode(otpState, challenge);
    }
}